package com.jacky.iot.resources;

import com.upokecenter.cbor.CBORObject;
import org.eclipse.californium.core.CoapResource;
import org.eclipse.californium.core.coap.CoAP;
import org.eclipse.californium.core.coap.MediaTypeRegistry;
import org.eclipse.californium.core.coap.Request;
import org.eclipse.californium.core.coap.Response;
import org.eclipse.californium.core.server.resources.CoapExchange;

// 多种数据格式支持
public class MultiFormatResource extends CoapResource {
    public MultiFormatResource(String name) {
        super(name);
        getAttributes().setTitle("Resource that exists in different content formats (text/plain utf8 and application/xml)");
        getAttributes().addContentType(MediaTypeRegistry.TEXT_PLAIN);
        getAttributes().addContentType(MediaTypeRegistry.APPLICATION_XML);
        getAttributes().addContentType(MediaTypeRegistry.APPLICATION_JSON);
        getAttributes().addContentType(MediaTypeRegistry.APPLICATION_CBOR);
    }

    @Override
    public void handleGET(CoapExchange exchange) {
        Request request = exchange.advanced().getRequest();

        Response response = new Response(CoAP.ResponseCode.CONTENT);
        String format = null;
        switch (exchange.getRequestOptions().getAccept()) {
            case MediaTypeRegistry.UNDEFINED:
            case MediaTypeRegistry.TEXT_PLAIN:
                response.getOptions().setContentFormat(MediaTypeRegistry.TEXT_PLAIN);
                format = "Status type: \"%s\" \nCode: \"%s\" \nMid: %d \nAccept: %d";
                break;

            case MediaTypeRegistry.APPLICATION_XML:
                response.getOptions().setContentFormat(MediaTypeRegistry.APPLICATION_XML);
                format = "<msg type=\"%s\" \ncode=\"%s\" \nmid=\"%d\" \naccept=\"%d\" />";
                break;

            case MediaTypeRegistry.APPLICATION_JSON:
                response.getOptions().setContentFormat(MediaTypeRegistry.APPLICATION_JSON);
                format = "{ \"type\":\"%s\", \n\"code\":\"%s\", \n\"mid\":%d, \naccept=\"%d\" }";
                break;

            case MediaTypeRegistry.APPLICATION_CBOR:
                // todo
                response.getOptions().setContentFormat(MediaTypeRegistry.APPLICATION_CBOR);
                CBORObject map = CBORObject.NewMap();
                map.set(CBORObject.FromObject("type"),CBORObject.FromObject(request.getType().name()));
                map.set(CBORObject.FromObject("code"),CBORObject.FromObject(request.getCode().name()));
                map.set(CBORObject.FromObject("mid"),CBORObject.FromObject(request.getMID()));
                map.set(CBORObject.FromObject("accept"),CBORObject.FromObject(request.getOptions()));
                response.setPayload(map.EncodeToBytes());
                break;

            default:
                response = new Response(CoAP.ResponseCode.NOT_ACCEPTABLE);
                format = "text/plain, application/xml, application/json, or application/cbor only";
                break;
        }

        if (format != null) {
            response.setPayload(String.format(format, request.getType(), request.getCode(), request.getMID(), request.getOptions().getAccept()));
        }

        exchange.respond(response);
    }
}
